package org.darcy.service.work.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.darcy.dao.WorkMapper;
import org.darcy.entity.CheckCollect;
import org.darcy.entity.CheckDelivery;
import org.darcy.entity.business.BusinessContract;
import org.darcy.entity.org.Staff;
import org.darcy.entity.privilege.SysUser;
import org.darcy.entity.work.WorkFlowObject;
import org.darcy.entity.work.WorkInstance;
import org.darcy.entity.work.WorkTask;
import org.darcy.framework.constant.SysConstant;
import org.darcy.framework.exception.BusinessException;
import org.darcy.framework.generic.GenericServiceImpl;
import org.darcy.framework.model.PageData;
import org.darcy.framework.model.PageParam;
import org.darcy.service.check.CheckCollectService;
import org.darcy.service.check.CheckDeliveryService;
import org.darcy.service.work.WorkService;
import org.darcy.service.work.WorkTaskService;
import org.darcy.utils.UserTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * Work 工作项服务实现
 */
@Service
@Slf4j
public class WorkServiceImpl extends GenericServiceImpl<WorkInstance> implements WorkService {

	@Autowired
	private WorkMapper mapper;

	@Autowired
	private WorkTaskService WorkTaskService;

	@Autowired
	private WorkNextService WorkNextService;

	@Autowired
	private CheckDeliveryService CheckDeliveryService;

	@Autowired
	private CheckCollectService CheckCollectService;

	@Override
	public WorkInstance getDetail(Integer id) {
		WorkInstance record = mapper.selectById(id);
		return record;
	}

	@Override
	public int delete(Object id) {
		super.delete(id);
		QueryWrapper<WorkTask> wrapper = new QueryWrapper<WorkTask>();
		wrapper.eq("work_id", id);
		WorkTaskService.deleteBatch(wrapper);
		return 1;
	}

	@Override
	public PageData<WorkInstance> page(PageParam<WorkInstance> param) {
		IPage<WorkInstance> queryPage = new Page<>(param.getQuery().getPageNum(), param.getQuery().getPageSize());
		IPage<WorkInstance> data = mapper.getPage(queryPage, param.getEntity());
		for (WorkInstance a : data.getRecords()) {
			a.setStatusName(a.fetchStatusName());
		}
		PageData<WorkInstance> pageData = new PageData<WorkInstance>(data, param);
		return pageData;
	}

	@Override
	public WorkInstance getBusinessWork(WorkInstance param) {
		if (StrUtil.isEmpty(param.getFormType())) {
			throw new BusinessException("查询参数有误，业务类型不能为空");
		}
		if (param.getFormId() == null) {
			throw new BusinessException("查询参数有误，业务表单id不能为空");
		}
		QueryWrapper<WorkInstance> wrapper = new QueryWrapper<WorkInstance>();
		wrapper.eq("form_type", param.getFormType()).eq("form_id", param.getFormId());
		if (param.getStatus() != null) {
			wrapper.eq("`status`", param.getStatus());
		}
		return this.getOne(wrapper);
	}

	@Override
	public void processWorkFlowObject(WorkFlowObject record, String formType) {
		WorkInstance param = WorkInstance.builder().formType(formType).formId(record.getId()).build();
		WorkInstance work = this.getBusinessWork(param);
		if (work == null) {						
			if (record.getId() > 0) {
				log.error("根据业务参数获取工作流信息出错，formType={}, formId={}", formType, record.getId());
			}
			return;
		}

		QueryWrapper<WorkTask> wrapper = new QueryWrapper<WorkTask>();
		wrapper.eq("work_id", work.getId());
		wrapper.orderByDesc("id");
		List<WorkTask> list = WorkTaskService.getList(wrapper);
		work.setAllTask(list);
		// 过滤抄送人员，方便前端渲染
		List<WorkTask> filteredList = list.stream()
				.filter(a -> !a.getStatus().equals(SysConstant.FlowStatus.STATUS9_CC)).collect(Collectors.toList());
		work.setMainTask(filteredList);
		record.setWork(work);
		processUser(record);
	}

	@Override
	public WorkFlowObject getWorkFlowObject(Integer formId, String formType) {
		WorkFlowObject data = new WorkFlowObject();
		WorkInstance param = WorkInstance.builder().formType(formType).formId(formId).build();
		WorkInstance work = this.getBusinessWork(param);
		if (work == null) {
			if (formId == 0) {
				// 表单新增，显示提交按钮
				data.setShowCommit(true);
			} else {
				log.error("根据业务参数获取工作流信息出错，formType={}, formId={}", formType, formId);
			}
			return data;
		}

		QueryWrapper<WorkTask> wrapper = new QueryWrapper<WorkTask>();
		wrapper.eq("work_id", work.getId());
		wrapper.orderByDesc("id");
		List<WorkTask> list = WorkTaskService.getList(wrapper);
		work.setAllTask(list);
		// 过滤抄送人员，方便前端渲染
		List<WorkTask> filteredList = list.stream()
				.filter(a -> !a.getStatus().equals(SysConstant.FlowStatus.STATUS9_CC)).collect(Collectors.toList());
		work.setMainTask(filteredList);
		work.setTask(filteredList.get(0));
		data.setWork(work);
		processUser(data);
		return data;
	}

	private void processUser(WorkFlowObject record) {
		// 处理工作任务列表
		record.setAaList(new ArrayList<Staff>());
		record.setCcList(new ArrayList<Staff>());
		WorkInstance work = record.getWork();
		boolean foundApprover = false;
		for (WorkTask a : work.getAllTask()) {
			// 审批人员
			if (!foundApprover && (work.getStatus().equals(SysConstant.FlowStatus.STATUS10_APPROVING)
					|| work.getStatus().equals(SysConstant.FlowStatus.STATUS100_APPROVED))) {
				Staff staff = new Staff();
				staff.setUid(a.getOperator());
				staff.setName(a.getOperatorName());
				record.getAaList().add(staff);
				foundApprover = true;
			}
			// 抄送人员
			if (a.getStatus().equals(SysConstant.FlowStatus.STATUS9_CC)) {
				Staff staff = new Staff();
				staff.setUid(a.getOperator());
				staff.setName(a.getOperatorName());
				record.getCcList().add(staff);
			}
		}

		WorkTask task = null;
		for (WorkTask a : record.getWork().getMainTask()) {
			if (a.getOperator().equals(UserTool.getLoginUserId())) {
				task = a;
				break;
			}
		}
		if (task == null) {
			record.setShowCommit(false);
			record.setShowApprove(false);
			return;
		}

		if (work.getStatus() == SysConstant.FlowStatus.STATUS0_DRAFT) {
			if (task.getStatus().equals(SysConstant.TaskStatus.STATUS1_DONE)) {
				record.setShowCommit(false);
			} else {
				record.setShowCommit(true);
			}
		} else if (work.getStatus() == SysConstant.FlowStatus.STATUS20_REJECT) {
			if (task.getComment().equals("审批拒绝")) {
				// 当前用户是审批者
				record.setShowCommit(false);
			} else {
				// 当前用户是提交者
				record.setShowCommit(true);
			}
		} else {
			record.setShowCommit(false);
		}

		if (work.getStatus().equals(SysConstant.FlowStatus.STATUS10_APPROVING)
				&& task.getStatus().equals(SysConstant.TaskStatus.STATUS0_TODO)) {
			record.setShowApprove(true);
		} else {
			record.setShowApprove(false);
		}
	}

	@Override
	public void addWorkTask(WorkFlowObject record, String title, String summary, String formType) {
		// 存草稿：同步生成工作项和工作任务
		WorkInstance param = WorkInstance.builder().formType(formType).formId(record.getId()).build();
		WorkInstance work = this.getBusinessWork(param);
		if (work == null) {
			String user = UserTool.getLoginUser().getRealName();
			work = WorkInstance.builder().formType(formType).formId(record.getId()).title(title).summary(summary)
					.operatorName(user).startTime(new Date()).build();
			if (record instanceof BusinessContract) {
				work.setGroupId(record.getId());
			}
			if (record instanceof CheckDelivery) {
				CheckDelivery d = (CheckDelivery) record;
				work.setGroupId(d.getContractId());
			}
			this.insert(work);
		}
		WorkTask draft = WorkTaskService.getDraftTask(work.getId());
		// 存草稿：同步生成我的工作任务
		if (draft == null) {
			SysUser user = UserTool.getLoginUser();
			draft = WorkTask.builder().workId(work.getId()).operator(user.getId()).operatorName(user.getRealName())
					.status(SysConstant.TaskStatus.STATUS0_TODO).comment(title).build();
			WorkTaskService.insert(draft);
		}
		// 采样办公室，收样，实验派工，公示：不用审批，直接通过
		if (formType.equals(SysConstant.FormType.CheckCaiYangDept)
				|| formType.equals(SysConstant.FormType.CheckShouYang)
				|| formType.equals(SysConstant.FormType.LibDispatch) || formType.equals(SysConstant.FormType.ShowPublic)
				|| formType.equals(SysConstant.FormType.HandOver) || formType.equals(SysConstant.FormType.CloseDept)
				|| formType.equals(SysConstant.FormType.CloseFinancial)
				|| formType.equals(SysConstant.FormType.Archive)) {
			CheckCollect collect = (CheckCollect) record;
			// 先模拟存草稿保存下数据
			if (formType.equals(SysConstant.FormType.LibDispatch)) {
				CheckCollectService.update(collect);
			}

			if (collect.getIsCommit()) {
				work.setStatus(SysConstant.FlowStatus.STATUS100_APPROVED);
				work.setStopTime(new Date());
				this.update(work);
				draft.setStatus(SysConstant.TaskStatus.STATUS1_DONE);
				draft.setUpdateTime(new Date());
				WorkTaskService.update(draft);
				if (formType.equals(SysConstant.FormType.CheckShouYang)) {
					// 收样提交
					WorkNextService.createCheckShouYangNext(collect.getId());
				} else if (formType.equals(SysConstant.FormType.LibDispatch)) {
					// 实验派工提交
					WorkNextService.createLibDispatchNext(collect.getId());
				} else if (formType.equals(SysConstant.FormType.ShowPublic)) {
					// 公示提交
					WorkNextService.createShowPublicNext(collect.getId());
				} else if (formType.equals(SysConstant.FormType.HandOver)) {
					// 交付提交
					WorkNextService.createHandOverNext(collect.getId());
				} else if (formType.equals(SysConstant.FormType.CloseDept)) {
					// 办公室结算提交
					WorkNextService.createCloseDeptNext(collect.getId());
				} else if (formType.equals(SysConstant.FormType.CloseFinancial)) {
					log.info("财务结算提交, collectId={}", collect.getId());
					WorkNextService.createCloseFinancialNext(collect);
				} else if (formType.equals(SysConstant.FormType.Archive)) {
					log.info("归档提交, deliveryId={}", collect.getDelivery().getId());
					CheckDeliveryService.archive(collect.getDelivery().getId());
				}
				return;
			}
		}
		// 提交：同步生成审批者的工作任务
		if (record.getAaList() != null && !record.getAaList().isEmpty()) {
			WorkTask approveTask = WorkTaskService.getApprovingTask(draft);
			if (approveTask.getId() == null) {
				Staff staff = record.getAaList().get(0);
				approveTask.setOperator(staff.getUid());
				approveTask.setOperatorName(staff.getName());
				WorkTaskService.insert(approveTask);
				// 把草稿任务置为已完成
				draft.setStatus(SysConstant.TaskStatus.STATUS1_DONE);
				draft.setReadStatus(2);
				WorkTaskService.update(draft);
				// 把工作项置为审批中
				work.setStatus(SysConstant.FlowStatus.STATUS10_APPROVING);
				this.update(work);
				// 提交：同步生成抄送者的工作任务
				if (record.getCcList() != null && !record.getCcList().isEmpty()) {
					for (Staff a : record.getCcList()) {
						// 如果抄送任务已存在，则不在增加
						WorkTask existCCTask = WorkTaskService.getCCTask(work.getId(), a.getUid());
						if (existCCTask != null) {
							continue;
						}
						WorkTask ccTask = approveTask.clone();
						ccTask.setId(null);
						ccTask.setOperator(a.getUid());
						ccTask.setOperatorName(a.getName());
						ccTask.setStatus(SysConstant.TaskStatus.STATUS9_CC);
						WorkTaskService.insert(ccTask);
					}
				}
			}
		}
	}

	@Override
	public WorkTask approve(WorkTask task) {
		Date now = new Date();
		WorkInstance record = this.getById(task.getWorkId());
		record.setUpdateTime(now);
		task.setReadStatus(2);
		task.setUpdateTime(now);

		if (task.getAgree()) {
			task.setStatus(SysConstant.TaskStatus.STATUS1_DONE);
			task.setComment("审批通过");
			record.setStatus(SysConstant.FlowStatus.STATUS100_APPROVED);
			record.setStopTime(now);
			WorkNextService.createNext(record);
		} else {
			task.setStatus(SysConstant.TaskStatus.STATUS1_DONE);
			task.setComment("审批拒绝");
			task.setCreateTime(now);
			record.setStatus(SysConstant.FlowStatus.STATUS20_REJECT);
			WorkTask firstOne = WorkTaskService.getById(task.getPid());
			// 原先的草稿任务置为拒绝
			firstOne.setStatus(SysConstant.TaskStatus.STATUS1_DONE);
			WorkTaskService.update(firstOne);
			// 重新生成一个任务
			WorkTask newTask = WorkTask.builder().pid(task.getId()).workId(firstOne.getWorkId())
					.operator(firstOne.getOperator()).operatorName(firstOne.getOperatorName())
					.comment(firstOne.getComment()).readStatus(0).createTime(now).updateTime(now).build();

			WorkTaskService.insert(newTask);
		}
		WorkTaskService.update(task);
		this.update(record);
		return task;
	}

	@Override
	public WorkTask getSummary() {
		WorkTask result = new WorkTask();
		Integer uid = UserTool.getLoginUserId();
		List<WorkTask> list = mapper.getSummary(uid);
		for (WorkTask a : list) {
			if (a.getStatus() == 0) {
				result.setCount1(a.getStatusCount());
			}
			if (a.getStatus() == 1) {
				result.setCount2(a.getStatusCount());
			}
			if (a.getStatus() == 9) {
				result.setCount3(a.getStatusCount());
			}
		}
		return result;
	}

	@Override
	public List<WorkInstance> getFlowList(Integer groupId) {
		QueryWrapper<WorkInstance> wrapper = new QueryWrapper<WorkInstance>();
		wrapper.eq("group_id", groupId);
		return this.getList(wrapper);
	}

}
